//#define USE_DUNGEONBUDDY_DLL
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Documents;
using Styx;
using Styx.CommonBot;
using Styx.Helpers;
using Styx.Patchables;
using Styx.Pathing;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using Styx.TreeSharp;
using Tripper.MeshMisc;
using Tripper.Navigation;
using Tripper.RecastManaged.Detour;
using Tripper.Tools.Math;
#if USE_DUNGEONBUDDY_DLL
using Bots.DungeonBuddyDll;
using Bots.DungeonBuddyDll.Attributes;
using Bots.DungeonBuddyDll.Helpers;

namespace Bots.DungeonBuddyDll.Dungeon_Scripts.Burning_Crusade
#else
    using Bots.DungeonBuddy.Attributes;
    using Bots.DungeonBuddy.Helpers;
    namespace Bots.DungeonBuddy.Dungeon_Scripts.Burning_Crusade
#endif

{
    public class SethekkHalls : Dungeon
    {
        #region Overrides of Dungeon

        private const float ShortcutRadius = 50;
        private readonly Vector3 _shortcutBlackspotLoc = new Vector3(44.46614f, 185.8761f, -10);
        private bool _shortcutBlocked;

        public override uint DungeonId
        {
            get { return 150; }
        }

        public override WoWPoint Entrance
        {
            get
            {
                if (_shortcutBlocked) _shortcutBlocked = false;
                return new WoWPoint(-3361.518, 4655.588, -101.0466);
            }
        }

        public override WoWPoint ExitLocation
        {
            get { return new WoWPoint(-9.0, -0.7, .001); }
        }

        public override void IncludeTargetsFilter(List<WoWObject> incomingunits, HashSet<WoWObject> outgoingunits)
        {
            foreach (var unit in incomingunits)
            {
                if (unit.Entry == CharmingTotemId) //  Charming Totem
                    outgoingunits.Add(unit);
            }
        }

        public override void WeighTargetsFilter(List<Targeting.TargetPriority> units)
        {
            foreach (var priority in units)
            {
                var unit = priority.Object as WoWUnit;
                if (unit != null)
                {
                    if (unit.Entry == CharmingTotemId) //  Charming Totem
                        priority.Score += 400;

                    if (unit.Entry == TimeLostControllersId && StyxWoW.Me.IsDps())
                        priority.Score += 210;

                    if (unit.Entry == SethekkProphetId && StyxWoW.Me.IsDps())
                        priority.Score += 200;

                    if (unit.Entry == TimeLostScryerId && StyxWoW.Me.IsDps())
                        priority.Score += 190;
                }
            }
        }

        public override void RemoveTargetsFilter(List<WoWObject> units)
        {
            units.RemoveAll(unit => unit is WoWPlayer);
        }

        public override void OnEnter()
        {
            ((MeshNavigator)Navigator.NavigationProvider).Nav.OnTileLoaded += Nav_OnTileLoaded;
        }

        public override void OnExit()
        {
            ((MeshNavigator)Navigator.NavigationProvider).Nav.OnTileLoaded -= Nav_OnTileLoaded;
        }

        private void Nav_OnTileLoaded(object sender, TileLoadedEventArgs e)
        {
            if (Me.MapId == LfgDungeon.MapId && ScriptHelpers.IsBossAlive("Talon King Ikiss"))
            {
                ApplyMeshArea(AreaType.Misc7, 60, _shortcutBlackspotLoc, ShortcutRadius, 50);
                _shortcutBlocked = true;
            }
        }

        public override MoveResult MoveTo(WoWPoint location)
        {
            if (!_shortcutBlocked && ScriptHelpers.IsBossAlive("Talon King Ikiss"))
            {
                ApplyMeshArea(AreaType.Misc7, 60, _shortcutBlackspotLoc, ShortcutRadius, 50);
                _shortcutBlocked = true;
            }
            if (_shortcutBlocked && !ScriptHelpers.IsBossAlive("Talon King Ikiss"))
            {
                ApplyMeshArea(AreaType.Ground, float.NaN, _shortcutBlackspotLoc, ShortcutRadius, 50);
                _shortcutBlocked = false;
            }

            return base.MoveTo(location);
        }

        #endregion

        private const uint CharmingTotemId = 20343;
        private const uint TimeLostControllersId = 18327;
        private const uint SethekkProphetId = 18325;
        private const uint TimeLostScryerId = 18319;
        private const uint SethekkSpiritId = 18703;
        private WoWUnit _ghost = null;


        private WoWUnit _ikiss;
        private WoWUnit _syth;

        private LocalPlayer Me
        {
            get { return StyxWoW.Me; }
        }

        private void ApplyMeshArea(AreaType area, float cost, Vector3 center, float radius, float height = 10)
        {
            var nav = Navigator.NavigationProvider as MeshNavigator;
            if (!float.IsNaN(cost))
                nav.Nav.QueryFilter.SetAreaCost(area, cost);
            var extents = new Vector3(radius, height, radius);
            PolygonReference[] polyRefs;

            center = NavHelper.ToNav(center);
            var status = nav.Nav.MeshQuery.QueryPolygons(center, extents, nav.Nav.QueryFilter.InternalFilter, 0x2000, out polyRefs);

            if (!status.Failed)
            {
                foreach (var polyRef in polyRefs)
                {
                    nav.Nav.Mesh.SetPolyArea(polyRef, (byte)area);
                }
            }
        }

        [EncounterHandler(54840, "Isfar", Mode = CallBehaviorMode.Proximity, BossRange = 30)]
        public Composite WatcherJhangQuestHandler()
        {
            const int terokksLegacyQuestId = 29606;
            WoWUnit unit = null;
            return new PrioritySelector(
                ctx => unit = ctx as WoWUnit,
                new Decorator(
                    ctx =>
                    !Me.Combat && !ScriptHelpers.WillPullAggroAtLocation(unit.Location) && unit.QuestGiverStatus == QuestGiverStatus.Available &&
                    Me.QuestLog.GetQuestById(terokksLegacyQuestId) == null && Me.QuestLog.GetCompletedQuests().All(q => q != terokksLegacyQuestId),
                    ScriptHelpers.CreatePickupQuest(() => unit, terokksLegacyQuestId)),
                new Decorator(
                    ctx => !Me.Combat && !ScriptHelpers.WillPullAggroAtLocation(unit.Location) && unit.QuestGiverStatus == QuestGiverStatus.TurnIn,
                    ScriptHelpers.CreateTurninQuest(() => unit)));
        }

        [EncounterHandler(0, "Root")]
        public Composite RootHandler()
        {
            AddAvoidObject(ctx => !Me.IsCasting, obj => Me.IsRange() && Me.IsMoving ? 10 : 6, SethekkSpiritId);

            return new PrioritySelector();
        }

        [EncounterHandler(18472, "Darkweaver Syth")]
        public Composite DarkweaverSythEncounter()
        {
            return new PrioritySelector(ctx => _syth = ctx as WoWUnit, ScriptHelpers.CreateSpreadOutLogic(ctx => true, () => _syth.Location, 15, 30));
        }

        [EncounterHandler(18473, "Talon King Ikiss")]
        public Composite TalonKingIkissEncounter()
        {
            var pilarLocations = new List<WoWPoint>
                                 {
                                     new WoWPoint(22.67584, 309.4335, 26.59805),
                                     new WoWPoint(67.06754, 308.9184, 26.62627),
                                     new WoWPoint(67.86166, 262.8065, 26.36894),
                                     new WoWPoint(22.76415, 264.541, 26.66963)
                                 };

            return new PrioritySelector(
                ctx => _ikiss = ctx as WoWUnit,
                ScriptHelpers.CreateLosLocation(
                    ctx => _ikiss.CastingSpellId == 38197 || _ikiss.CastingSpellId == 40425,
                    () => _ikiss.Location,
                    () => pilarLocations.OrderBy(loc => StyxWoW.Me.Location.DistanceSqr(loc)).FirstOrDefault(),
                    () => 10));
        }
    }
}